package org.gen.code.gen.controller;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.gen.code.core.constant.Constants;
import org.gen.code.core.constant.GenConstants;
import org.gen.code.core.domain.GenForm;
import org.gen.code.core.domain.GenTableColumn;
import org.gen.code.core.response.R;
import org.gen.code.db.dao.DbConfigDao;
import org.gen.code.db.domain.DbConfig;
import org.gen.code.gen.domain.TableInfo;
import org.gen.code.gen.service.CodeService;
import org.gen.code.utils.*;
import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 代码生成控制层
 */
@RestController
@RequestMapping("gen/")
public class GenController {

    @Autowired
    private CodeService codeService;

    @Autowired
    private DbConfigDao dbConfigDao;


    /**
     * 获取数据库表信息
     *
     * @param jsonObject
     * @return
     */
    @PostMapping("/getTableList")
    public R getTableList(@RequestBody JSONObject jsonObject) {
        Long id = jsonObject.getLong("id");
        String tableName = jsonObject.getStr("tableName");
        DbConfig dbConfig = dbConfigDao.getReferenceById(Long.valueOf(id));
        List<TableInfo> allTables = codeService.getAllTables(dbConfig);
        if (StringUtils.isNotEmpty(tableName)) {
            allTables = allTables.stream().filter(item -> item.getTableName().contains(tableName)).collect(Collectors.toList());
        }
        return R.success(allTables);
    }


    /**
     * 生成代码
     *
     * @param genForm
     * @return
     */
    @PostMapping("/code")
    public R genForm(@RequestBody GenForm table) throws IOException {
        // 查询表信息  字段信息
        TableInfo allColumns = codeService.getAllColumns(table.getTableName(), table.getDbConfig());
        List<GenTableColumn> allColumnList = allColumns.getListColumn();
        allColumnList.parallelStream().forEach(allColumn -> {
            // Java字段设置
            GenUtils.initColumnField(allColumn, table);
        });
        table.setColumns(allColumnList);
        // 设置主子表信息
        setSubTable(table);
        // 设置主键列信息
        setPkColumn(table);
        // 初始化表信息
        GenUtils.initTable(table);
        // 模板初始化
        VelocityInitializer.initVelocity();
        VelocityContext context = VelocityUtils.prepareContext(table);
        // 获取模板列表
        List<String> templates = VelocityUtils.getTemplateList(table);
        for (String template : templates) {
            // 渲染模板
            StringWriter sw = new StringWriter();
            Template tpl = Velocity.getTemplate(template, Constants.UTF8);
            tpl.merge(context, sw);
            try {
                String path = getGenPath(table, template);
                FileUtils.writeUtf8String(sw.toString(), path);
            } catch (Exception e) {
                throw new ServiceException("渲染模板失败，表名：" + table.getTableName());
            }
        }
        return R.success("代码生成成功");
    }


    /**
     * 设置主键列信息
     *
     * @param table 业务表信息
     */
    public void setPkColumn(GenForm table) {
        for (GenTableColumn column : table.getColumns()) {
            if (column.isPk()) {
                table.setPkColumn(column);
                break;
            }
        }
        if (ObjectUtil.isNull(table.getPkColumn())) {
            table.setPkColumn(table.getColumns().get(0));
        }
        if (GenConstants.TPL_SUB.equals(table.getTplCategory())) {
            for (GenTableColumn column : table.getSubTable().getColumns()) {
                if (column.isPk()) {
                    table.getSubTable().setPkColumn(column);
                    break;
                }
            }
            if (ObjectUtil.isNull(table.getSubTable().getPkColumn())) {
                table.getSubTable().setPkColumn(table.getSubTable().getColumns().get(0));
            }
        }
    }

    /**
     * 设置主子表信息
     *
     * @param table 业务表信息
     */
    public void setSubTable(GenForm table) {
        String subTableName = table.getSubTableName();
        if (StringUtils.isNotEmpty(subTableName)) {
            TableInfo allColumns = codeService.getAllColumns(subTableName, table.getDbConfig());
//            table.setSubTable();
        }
    }


    /**
     * 获取代码生成地址
     *
     * @param table    业务表信息
     * @param template 模板文件路径
     * @return 生成地址
     */
    public static String getGenPath(GenForm table, String template) {
        String genPath = table.getGenPath();
        if (StringUtils.equals(genPath, "/")) {
            return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
        }
        return genPath + File.separator + VelocityUtils.getFileName(template, table);
    }
}
